import {combineReducers, createStore} from "redux";

const utils = {
    /**
     * 遍历对象
     * @param obj 对象
     * @param callback 回调函数
     */
    foreach: (obj, callback) => {
        let type = typeof obj;
        if (type === "array") {
            obj.forEach(callback);
        } else {
            for (let el in obj) {
                callback(el, obj[el], obj);
            }
        }
    },
    /**
     *
     * @param model {namespace: string,state: any,reducers: object}
     * @returns {function(*=, *=): {[p: string]: *}}
     */
    reducerWrapper: (model) => (state = model.state, action) => {
        let stateNew = state;
        utils.foreach(model.reducers, (name, reducer, obj) => {
            if (action.type === (model.namespace + "/" + name)) {
                stateNew = reducer(stateNew, action);
                return false;
            }
        });
        return stateNew;
    },
    /**
     *
     * @param models
     * @returns {Store<{}, AnyAction> & Store<S & {}, A> & {dispatch: {}}}
     */
    createStore: (models) => {
        let modelWrapper = {};
        utils.foreach(models, (name, model, reducersGroup) => {
            modelWrapper[model.namespace] = utils.reducerWrapper(model);
        });
        return createStore(combineReducers({...modelWrapper}));
    },
    val: (selector) => {
        let el;
        if (selector.startsWith("#")) {
            el = document.getElementById(selector.substr(1));
        } else if (selector.startsWith(".")) {
            el = document.getElementsByClassName(selector.substr(1)).item(0);
        } else {
            el = document.getElementsByName(selector).item(0);
        }
        return el ? el.value : null;
    },
    storage: {
        json: (key, value) => {
            if (value) {
                localStorage.setItem(key, JSON.stringify(value));
            } else {
                return JSON.parse(localStorage.getItem(key));
            }
        }
    }
}

export default utils;